<template>
  <div id="hy-swiper">
    <!-- 触摸事件：touchstart：触摸开始，多点触控，后面的手指同样会触发
                     touchmove：接触点改变，滑动时
                     touchend：触摸结束，手指离开屏幕时-->
     <div class="swiper" @touchstart="touchStart" @touchmove="touchMove" @touchend="touchEnd" >
         <slot></slot>
     </div>
     <!-- indicator:是指示信号的意思 -->
     <slot name="indicator"></slot>

     <div class="indicator">

        <slot name="indicator" v-if="showIndicator && slideCount>1">
            <div v-for="(item,index) in slideCount" class="indi-item" :class="{active:index === currentIndex-1}" :key="index"></div>
        </slot>

     </div>

  </div>
</template>

<script>
export default {

  name:'Swiper',

  props:{

    interval:{
     
     type:Number,
     default:2000

    },

    animDuration:{
      
      type:Number,
      default:1000

    },

    moveRatio:{

      type:Number,
      default:0.25

    },

    showIndicator:{

      type:Boolean,
      default:true

    }

  },

   data:function(){

    return {

     slideCount:0,   //元素个数
     totalWidth:0,   //swiper的宽度
     swiperStyle:{}, //swiper样式
     currentIndex:1, //当前的index
     scrolling:false, //是否正在滚动

    }

   },
   //生命周期函数：mounted:页面初始化完成后
   mounted:function(){

    // 操作Dom,在前后添加slide
    setTimeout(() => {

     this.handleDom();

    // 2:开启定时器
    this.startTimer();

    },100)
   },

   methods: {

    //  定时器操作
    startTimer:function(){

      // 创建一个定时器
      this.playTimer= window.setInterval(() => {

        this.currentIndex++;
        this.scrollContent(-this.currentIndex * this.totalWidth);

      },this.interval)

    },

    stopTimer: function(){
    
      // 清除定时器
      window.clearInterval(this.playTimer);

    },

 

  //  滚动到正确的位置
  scrollContent:function(currentPosition){

    // 0.设置正在滚动
    this.scrolling = true;

    // 1.开始滚动动画
    this.swiperStyle.transition = 'transform' + this.animDuration + 'ms';
    this.setTransform(currentPosition);

    // 2.判断滚动到的位置
    this.checkPositon();

    // 3.滚动完成
    this.scrolling = false

  },


  // 校验正确的位置
  checkPositon:function(){

    window.setTimeout(() => {

    //1.校验正确的位置
    this.swiperStyle.transition = '0ms';
    if(this.currentIndex >= this.slideCount + 1){

       this.currentIndex = 1;
       this.setTransform(-this.currentIndex * this.totalWidth);

    }else if(this.currentIndex <= 0){

       this.currentIndex = this.slideCount;
       this.setTransform(-this.currentIndex * this.totalWidth);

    }

    // 2.结束移动后的回调
    this.$emit('transitionEnd', this.currentIndex-1);

    },this.animDuration)

  },

  // 设置滚动的位置
  setTransform: function(position){

     this.swiperStyle.transition = `translate3d(${position}px,0,0)`;
     this.swiperStyle['-webkit-transform'] = `translate3d(${position}px, 0 ,0)`;
     this.swiperStyle['-ms-transform'] = `translate3d(${position}px, 0 ,0)`;

  },


  // 操作DOM，在DOM前后添加slide
  handleDom:function(){

    //1. 获取要操作的元素
    let swiperEl = document.querySelector('.swiper');
    let slidesEls = swiperEl.getElementsByClassName('slide');

    //2.保存个数
    this.slideCount = slidesEls.length;

    //3.如果大于一个，那么在前后分别添加一个slide
    if(this.slideCount > 1){

       let cloneFirst = slidesEls[0].cloneNode(true);
       let cloneLast = slidesEls[this.slideCount-1].cloneNode(true);
       swiperEl.insertBefore(cloneLast,slidesEls[0]);
       swiperEl.appendChild(cloneFirst);
       this.totalWidth = swiperEl.offsetWidth;
       this.swiperStyle = swiperEl.style;

    }

    //4.让swiper元素，显示第一个（目前是显示前面添加的最后一个元素）
    this.setTransform(-this.totalWidth);

   
  },

  // 拖动事件的处理
  touchStart:function(e){

  //1.如果正在滚动，不可以拖动
  if(this.scrolling) return;

  //2.停止定时器
  this.stopTimer();

  //3.保存开始滚动的位置
  this.startX = e.touches[0].pageX;
  },

  touchMove:function(e){
 
    //1.计算出用户拖动的距离
    this.currentX = e.touches[0].pageX;
    this.distance = this.currentX - this.startX;
    let currentPosition = -this.currentIndex * this.totalWidth;
    let moveDistance = this.distance + currentPosition;

    //2.设置当前的位置
    this.setTransform(moveDistance);
       
  },

  touchEnd:function(e){

    //1.获取移动的距离
    let currentMove = Math.abs(this.distance);

    // 判断最终的距离
    if(this.distance === 0){

      return

    }else if(this.distance > 0 && currentMove > this.totalWidth * this.moveRatio){

    //向右移动超过0.5
    this.currentIndex--
    }else if(this.distance < 0 && currentMove > this.totalWidth * this.moveRatio){

    //向左移动超过0.5
    this.currentIndex++

    }

    // 3.移动到正确的位置
    this.scrollContent(-this.currentIndex * this.totalWidth);

    // 4.移动完成后重新开启定时器
    this.startTimer();

  },


  // 控制上一个，下一个
  previous: function(){

    this.changeItem(-1);

  },

  next:function(){

    this.changeItem(1);

  },

  changeItem:function(num){

    //1.移除定时器
    this.stopTimer();

    //2.修改index和位置
    this.currentIndex += num;
    this.scrollContent(-this.currentIndex * this.totalWidth);

    //3.添加定时器
    this.startTimer();

  }

  }

}


</script>

<style scoped>

#hy-swiper{

   overflow: hidden;
   position: relative;

}

.swiper{

   display: flex;

}

.indicator{

   display: flex;
   justify-content: center;

   position: absolute;
   widows: 100%;
   bottom: 8px;
}


.indi-item{

   box-sizing: border-box;
   width: 8px;
   height: 8px;
   border-radius: 4px;
   background-color: #ffffff;
   line-height: 8px;
   text-align: center;
   font-size: 12px;
   margin: 0 5px;

}


.indi-item.active{

   background-color: rgba(212,62,46, 1.0);

}

</style>